/**
 * Author: Zane
 * Email: 873934580@qq.com
 * Date: 2023/5/3
 */
import type { IRequestConfig } from '@ptadmin/request'
import type { AxiosRequestConfig } from 'axios'
import type { anyObj } from '@/types'
import { createRequest } from '@ptadmin/request'
import { error, getUri, success, routeNamePush } from '@/utils'
import { extend } from 'lodash-es'
import { useSystem } from '@/store'

export interface IResponse<T = any> {
    code: number
    message: string
    data?: T
}

export interface IResponseRows<T = any> extends IResponse {
    data: {
        total: number
        results: T[]
    }
}

const options: IRequestConfig = {
    loading: false,
    showMessage: true,
    showSuccessMessage: true,
    showErrorMessage: true,
    noLoginCode: 100007,
    errorFun: (data: any) => {
        error(data.message)
    },
    successFun: (msg) => {
        success(msg)
    },
    noLoginFun: async () => {
        // TODO 考虑完成一个无感刷新token
        await routeNamePush('login')
    },
}

const getOptions = (option: IRequestConfig = {}) => {
    options['authorization'] = 'Bearer ' + useSystem().getToken() ?? ''
    if (Object.keys(option).length > 0) {
        return extend(options, option)
    }

    return options
}

const create = <T>(_config: AxiosRequestConfig, option: IRequestConfig = {}) => {
    return createRequest<T>(_config, getOptions(option))
}

export const getAuth = () => {
    return {
        headers: {
            authorization: 'Bearer ' + useSystem().getToken() ?? '',
        },
    }
}

export const get = <T = any>(url: string, params: anyObj = {}, option: IRequestConfig = {}) => {
    const config: AxiosRequestConfig = {
        baseURL: getUri(),
        method: 'GET',
        url,
        params: { ...params },
    }

    return create<T>(config, option)
}

export const put = <T = any>(url: string, params: anyObj = {}, option: IRequestConfig = {}) => {
    const config: AxiosRequestConfig = {
        baseURL: getUri(),
        method: 'PUT',
        url,
        data: { ...params },
    }

    return create<T>(config, option)
}

export const post = <T = any>(url: string, params: anyObj = {}, option: IRequestConfig = {}) => {
    const config: AxiosRequestConfig = {
        baseURL: getUri(),
        method: 'POST',
        url,
        data: { ...params },
    }
    return create<T>(config, option)
}

export const del = <T = any>(url: string, params: anyObj = {}, option: IRequestConfig = {}) => {
    const config: AxiosRequestConfig = {
        baseURL: getUri(),
        method: 'DELETE',
        url,
        params: { ...params },
    }

    return create<T>(config, option)
}

export const patch = <T = any>(url: string, params: anyObj = {}, option: IRequestConfig = {}) => {
    const config: AxiosRequestConfig = {
        baseURL: getUri(),
        method: 'PATCH',
        url,
        params: { ...params },
    }

    return create<T>(config, option)
}

export const $http = {
    get,
    put,
    del,
    post,
    patch,
}
